<template>
  <x-layout-main class="m-system-dictionary">
    <n-grid :x-gap="10">
      <!--列表-->
      <n-gi :span="12">
        <n-card :segmented="{ content: true }" :bordered="false" size="small" style="position: sticky; top: 12px">
          <template #header>字典列表</template>
          <x-data-table
            ref="tableElRef"
            v-model:immediate="immediate"
            :params="params"
            :columns="columns"
            :row-props="rowProps"
          >
            <template #tableTitle>
              <div class="inquiry">
                <div class="flex">
                  <n-input-group>
                    <n-input
                      v-model:value="formData.dictName"
                      clearable
                      placeholder="请输入字典名称"
                      @keyup.enter="onInquiry"
                    />
                    <x-button icon="icon-076" type="primary" ghost @click="onInquiry">查询</x-button>
                  </n-input-group>
                  <x-button icon="icon-037" type="primary" @click="onAdd">新建</x-button>
                </div>
              </div>
            </template>
          </x-data-table>
        </n-card>
      </n-gi>
      <!--编辑-->
      <n-gi :span="12">
        <n-card :segmented="{ content: true }" :bordered="false" size="small">
          <template #header>
            <n-space>
              <x-icon name="icon-029" />
              <span>{{ editTitle }}</span>
            </n-space>
          </template>
          <n-alert type="info">从左侧列表选择一项后，进行编辑</n-alert>
          <div class="edit">
            <x-form
              v-if="currentRow"
              ref="formRef"
              v-model:model="currentRow"
              :rules="rules"
              :label-width="90"
              :disabled="isEditDisabled"
              label-placement="left"
            >
              <n-form-item label="名称" path="dictName">
                <n-input
                  v-model:value="currentRow.dictName"
                  :disabled="!!currentRow.type"
                  placeholder="请输入字典名称"
                  @change="handleChange"
                />
              </n-form-item>
              <n-form-item label="描述" path="remark">
                <n-input v-model:value="currentRow.remark" placeholder="请输入字典描述" />
              </n-form-item>
              <n-form-item label="选项" path="itemVoList">
                <div v-if="currentRow.itemVoList" class="list">
                  <x-button :disabled="isEditDisabled" type="primary" size="small" ghost @click="onPushRow">
                    新增选项
                  </x-button>
                  <n-table style="margin: 10px 0">
                    <thead>
                      <tr>
                        <th>字典值</th>
                        <th>字典值注释</th>
                        <th width="100">排序</th>
                        <th>操作</th>
                      </tr>
                    </thead>
                    <tbody>
                      <tr v-for="item in currentRow.itemVoList" :key="item.uuid">
                        <td>
                          <n-input v-model:value="item.dictValue" placeholder="请输入字典值" />
                        </td>
                        <td>
                          <n-input v-model:value="item.dictNote" placeholder="请输入字典值注释" />
                        </td>
                        <td>
                          <n-input-number v-model:value="item.sortNum" :show-button="false" placeholder="排序" />
                        </td>
                        <td>
                          <x-button
                            :disabled="isEditDisabled"
                            type="error"
                            size="small"
                            ghost
                            @click="onRemoveRow(item)"
                          >
                            删除
                          </x-button>
                        </td>
                      </tr>
                    </tbody>
                  </n-table>
                  <x-button
                    v-if="currentRow.itemVoList.length > 10"
                    :disabled="isEditDisabled"
                    type="primary"
                    size="small"
                    ghost
                    @click="onPushRow"
                  >
                    新增选项
                  </x-button>
                </div>
              </n-form-item>
              <n-form-item style="display: flex; justify-content: center">
                <x-button :loading="loading" type="primary" @click="submitForm">保存</x-button>
                <x-button type="primary" ghost @click="resetForm">重置</x-button>
              </n-form-item>
            </x-form>
          </div>
        </n-card>
      </n-gi>
    </n-grid>
  </x-layout-main>
</template>

<script lang="ts">
  import { v4 as uuidv4 } from 'uuid'
  import { computed, defineComponent, reactive, toRefs, h, ref } from 'vue'
  import {
    NGrid,
    NGi,
    NCard,
    NSpace,
    NAlert,
    NFormItem,
    NInput,
    NInputGroup,
    NInputNumber,
    NTable,
    NText,
    useMessage,
    NPopconfirm
  } from 'naive-ui'
  import { XIcon, XDataTable, XLayoutMain, XForm, XButton } from '@/components'
  import { useStore } from '@/store'
  import { useAuthority, useClipboard } from '@/hooks'

  export default defineComponent({
    name: 'SystemDictionary',
    components: {
      NGrid,
      NGi,
      NCard,
      NSpace,
      NAlert,
      NFormItem,
      NInput,
      NInputGroup,
      NInputNumber,
      NTable,
      XLayoutMain,
      XDataTable,
      XIcon,
      XForm,
      XButton
    },
    setup() {
      const $authority = useAuthority()
      const $store = useStore()
      const $message = useMessage()
      const { toClipboard } = useClipboard()
      const formRef: any = ref(null)
      const tableElRef: any = ref(null)
      const $state: any = reactive({
        immediate: true,
        loading: false,
        formData: {
          dictName: null
        },
        params: computed(() => {
          return {
            actions: 'system/getSystemDictionary',
            data: $state.formData
          }
        }),
        currentRow: null,
        rules: {
          dictName: {
            required: true,
            message: '请输入字典名称',
            trigger: 'blur'
          },
          remark: {
            required: true,
            message: '请输入字典描述',
            trigger: 'blur'
          },
          itemVoList: {
            required: true,
            validator(rule: any, value: []) {
              if (value && value.length) {
                return true
              } else {
                return new Error('请填写选项内容')
              }
            },
            trigger: 'change'
          }
        },
        editTitle: computed(() => {
          return $state.currentRow ? ($state.currentRow.type ? '编辑字典' : '新建字典') : '新建/编辑字典'
        }),
        columns: [
          {
            title: '名称',
            key: 'dictName',
            render(row: { dictName: string }) {
              return h(
                NSpace,
                {
                  vertical: true
                },
                () => [
                  h(NText, null, () => row.dictName),
                  h(
                    XButton,
                    {
                      ghost: true,
                      size: 'tiny',
                      onClick: (e: any) => {
                        e.stopPropagation()
                        toClipboard(row.dictName)
                      }
                    },
                    () => '复制'
                  )
                ]
              )
            }
          },
          {
            title: '描述',
            key: 'remark'
          },
          {
            title: '修改时间',
            key: 'createdAt'
          },
          {
            title: '操作',
            align: 'center',
            key: 'tools',
            render(row: { dictName: string }) {
              return h(
                NPopconfirm,
                {
                  onPositiveClick: () => {
                    handleRemoveDictRow(row.dictName)
                  }
                },
                {
                  default: () => '确定要删除此字典值？',
                  trigger: () =>
                    h(
                      XButton,
                      {
                        text: true,
                        type: 'error',
                        onClick: (e: any) => {
                          e.stopPropagation()
                        }
                      },
                      { default: () => '删除' }
                    )
                }
              )
            }
          }
        ],
        // 点击表单行操作
        rowProps: (row: { dictName: string }) => {
          return {
            // class: $state.currentRow && $state.currentRow.dictName === row.dictName ? 'is-active' : null,
            style: 'cursor: pointer;',
            onClick: () => {
              formRef.value && formRef.value.resetDefaultValue()
              // $state.currentRow = null
              $store
                .dispatch('system/getSystemDictionaryDetail', {
                  dictName: row.dictName
                })
                .then((res) => {
                  const data = res.data
                  if (data) {
                    data.type = 1 // 编辑
                    data.itemVoList?.forEach((item: any) => {
                      item.uuid = uuidv4()
                    })
                    // 根据排序值排序
                    data.itemVoList = data.itemVoList?.sort((a: { sortNum: number }, b: { sortNum: number }) => {
                      return a.sortNum - b.sortNum
                    })
                  }
                  $state.currentRow = data
                })
            }
          }
        },
        isEditDisabled: computed(() => {
          // return !$authority.is('字典表-编辑')
          return false
        })
      })

      // 主动查询
      const onInquiry = () => {
        $state.immediate = true
      }

      // 新增
      const onAdd = () => {
        formRef.value && formRef.value.resetDefaultValue()
        $state.currentRow = {
          type: 0,
          dictName: null,
          remark: null,
          itemVoList: [
            {
              uuid: uuidv4(),
              dictValue: null, //字典值
              dictNote: null, //字典值注释
              sortNum: 1 //排序
            }
          ]
        }
      }

      // 增加行
      const onPushRow = () => {
        $state.currentRow.itemVoList.push({
          uuid: uuidv4(),
          dictValue: null, //字典值
          dictNote: null, //字典值注释
          sortNum: $state.currentRow.itemVoList?.length + 1 //排序
        })
      }
      // 删除行
      const onRemoveRow = (row: any) => {
        const index = $state.currentRow.itemVoList.findIndex((item: any) => item.uuid === row.uuid)
        $state.currentRow.itemVoList.splice(index, 1)
      }

      // 重置
      const resetForm = () => {
        formRef.value.resetFields()
      }

      // 提交
      const submitForm = () => {
        formRef.value.validate((errors: []) => {
          if (!errors) {
            $state.loading = true
            $store
              .dispatch('system/setSystemDictionaryDetail', $state.currentRow)
              .then(() => {
                $message.success('执行成功')
                $state.loading = false
                $state.immediate = true

                if ($state.currentRow.type) {
                  // 编辑成功后更新初始重置值
                  formRef.value && formRef.value.resetDefaultValue($state.currentRow)
                } else {
                  // 新建成功后，清除右则数据
                  onAdd()
                }
              })
              .catch(() => {
                $state.loading = false
              })
            // $message.success('验证成功')
          } else {
            $message.error('验证失败，请填写完整信息')
          }
        })
      }

      // 值发生变化时，转换成大写
      const handleChange = (value: string) => {
        // 重新赋值之后，光标会发生变化。所以采用change方式
        $state.currentRow.dictName = value.toUpperCase()
      }

      // 删除字典值
      const handleRemoveDictRow = (dictName: string) => {
        $store
          .dispatch('system/removeSystemDictionary', {
            dictName
          })
          .then(() => {
            $message.success('执行成功')
            $state.loading = false
            $state.immediate = true
          })
          .catch(() => {
            $state.loading = false
          })
      }

      return {
        ...toRefs($state),
        formRef,
        tableElRef,
        onInquiry,
        onAdd,
        onPushRow,
        onRemoveRow,
        resetForm,
        submitForm,
        handleChange,
        handleRemoveDictRow
      }
    }
  })
</script>

<style lang="scss" scoped>
  .m-system-dictionary {
    .inquiry {
      display: inline-block;
      .n-input-group {
        margin-right: 10px;
      }
    }
    .edit {
      padding-top: 20px;
      .x-button {
        & + .x-button {
          margin-left: 10px;
        }
      }
      .list {
        width: 100%;
      }
    }
  }
</style>
